package com.kintreda.ieco_server.core.web;

import java.io.*;
import java.net.URLEncoder;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.coobird.thumbnailator.Thumbnails;
import com.kintreda.ieco_server.util.DateUtil;
import com.kintreda.ieco_server.util.StringUtil;

import com.kintreda.ieco_server.util.file.FileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

/***
 * 文件上传
 */
@Controller
public class FileTransferController extends BaseController{

	//允许格式
	@Value("#{properties['upload.allow']}")  
	protected String allow;
	
	//是否压缩
	@Value("#{properties['upload.compress']}")  
	protected boolean compress;
	
	//图像大小限制，超过则压缩
	@Value("#{properties['upload.image_compress_size']}")  
	protected Long image_compress_size;
	
	//保存地址
	@Value("#{properties['upload.target']}")  
	protected String target;
	
	protected boolean isImage(String suffix) {
		return Arrays.asList(new String[] {"png","jpg","gif"}).contains(suffix);
	}
	
	protected boolean isAllow(String suffix) {
		if(StringUtils.isBlank(suffix)){
			return false;
		}
		String[] allow_suffix = allow.split(",");
		for(int i = 0; i < allow_suffix.length; i++){
			if(StringUtils.equals(allow_suffix[i], suffix)){
				return true;
			}
		}
		return false;
	}
	
	@RequestMapping(value = "/upload",method = RequestMethod.GET)
	public String upload(){
		return "helper/upload";
	}
	
	
	/***
	 * 图片上传
	 * @param request 请求
	 * @param compress 是否压缩
	 * @param quality 压缩质量比例
	 * @return
	 */
	@RequestMapping(value = "/upload",method = RequestMethod.POST)
	@ResponseBody
	public Object upload(HttpServletRequest request,Integer compress,String quality){
		
		Map<String,Object> json = new HashMap<String,Object>();
		
		MultipartHttpServletRequest fileRequest = (MultipartHttpServletRequest)request;
		if(fileRequest != null){
			
			//所有上传文件控件名称
			Iterator<String> fileNames =  fileRequest.getFileNames();
			//原文件名
			String fileName = null;
			//该字段所有文件
			List<MultipartFile> files = null;
			MultipartFile file = null;
			//后缀
			String suffix = null;
			//新文件名
			String tempFileName = null;
			//文件夹
			String folder = target + DateUtil.getDate(DateUtil.YYYYMM) + File.separator;
			
			File targetFolder = new File(folder);
			if(!targetFolder.exists()){
				if(!targetFolder.mkdirs()){
					return R.error("创建上传文件夹错误");
				}
			}
			//保存后路径
			Map<String,Object> fileSaved = null;
			List<Object> fileList = new ArrayList<>();
			File transferTo = null;
			
			while (fileNames != null && fileNames.hasNext()) {
				fileName = fileNames.next();
				files = fileRequest.getFiles(fileName);
				if(files != null){
					fileSaved = new HashMap<>();
					for(int i = 0; i < files.size(); i++){
						file = files.get(i);
						suffix = FilenameUtils.getExtension(file.getOriginalFilename());
						//检查后缀是否允许
//						if(!isAllow(suffix)){
//							continue;
//						}
						tempFileName = StringUtil.getUUID() + "." + suffix;

						fileSaved.put("path", DateUtil.getDate(DateUtil.YYYYMM) + "/" + tempFileName);
						fileSaved.put("original_filename",file.getOriginalFilename());
						fileSaved.put("length",file.getSize());
						fileList.add(fileSaved);
						try {
							transferTo = new File(folder + tempFileName);
							file.transferTo(transferTo);
							
							//图像压缩,大于image_compress_size则压缩
							if(isImage(suffix) && transferTo.length() / 1024L > image_compress_size){
								if(compress != null && compress > 0 && StringUtils.isNotBlank(quality)){
									Thumbnails.of(transferTo.getAbsolutePath())
									.size(1920, 1080)
									.outputQuality(Float.parseFloat(quality))
									.toFile(transferTo.getAbsolutePath());
								}else{
									Thumbnails.of(transferTo.getAbsolutePath())
									.size(1920, 1080)
									.toFile(transferTo.getAbsolutePath());
								}
							}
						} catch (IllegalStateException | IOException e) {
							e.printStackTrace();
						}
					}
					if(fileSaved.size() > 0){
						json.put(fileName, fileList);
					}
				}
			}
		}
		System.out.println(json);
		return R.ok().put("files", json);
	}


	/**
	 *
	 * @param file
	 * @param fileDirectory
	 * @return 文件路径+文件实际名称
	 * @throws Exception
	 */
	@RequestMapping("/upload/save")
	@ResponseBody
	public Object save(@RequestParam(required = false) MultipartFile file, @RequestParam(required = false) String fileDirectory )throws Exception{
		String fileName = "";
		String date = DateUtil.getDate(DateUtil.YYYY_MM_DD);
		if (!file.isEmpty()){
			String filePath = target + fileDirectory + "/" + date;
			fileName = FileUpload.fileUp(file,filePath, UUID.randomUUID().toString().trim().replaceAll("-", ""));

		}

		return "/" + fileDirectory  + "/" + date + "/" + fileName + "/" + file.getOriginalFilename();
	}

	@RequestMapping("/multiView/{fileDirectory}")
	public ModelAndView uploadView(ModelAndView view, @PathVariable String fileDirectory){
		view.setViewName("helper/upload");
		view.addObject("fileDirectory",fileDirectory);
		return view;
	}



	@RequestMapping(value = "/new_upload",method = RequestMethod.GET)
	public String newUpload(){
		return "helper/new_upload";
	}


	/**
	 * 下载
	 * @param fileName 文件名称
	 * @param filePath 文件路径
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/download")
	public void download(String fileName , String filePath, HttpServletRequest request, HttpServletResponse response){

		response.setContentType("text/html;charset=utf-8");
		try {
			request.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		java.io.BufferedInputStream bis = null;
		java.io.BufferedOutputStream bos = null;

		String downLoadPath = target + filePath;  //注意不同系统的分隔符
		//	String downLoadPath =filePath.replaceAll("/", "\\\\\\\\");   //replace replaceAll区别 *****
		System.out.println(downLoadPath);

		try {
			long fileLength = new File(downLoadPath).length();
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "utf-8"));
			response.setHeader("Content-Length", String.valueOf(fileLength));
			bis = new BufferedInputStream(new FileInputStream(downLoadPath));
			bos = new BufferedOutputStream(response.getOutputStream());
			byte[] buff = new byte[2048];
			int bytesRead;
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bis != null)
				try {
					bis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if (bos != null)
				try {
					bos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}

}
